package com.android.launcher3;

import java.util.HashMap;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;

/**
 * 此代码已经完整 .
 * 
 * @author SoftW
 */
public class IconCache {

	public static final String TAG = "Launcher.IconCache";
	private final Utilities.BubbleText mBubble;
	private final Bitmap mDefaultIcon;
	private final HashMap<ComponentName, CacheEntry> mCache;
	private final LauncherApplication mContext;
	private final PackageManager mPackageManager;
	private static final int INITIAL_ICON_CACHE_CAPACITY = 50;

	/**
	 * Creates a new IconCache object.
	 * 
	 * @param application
	 */
	public IconCache(final LauncherApplication application) {
		this.mCache = new HashMap<ComponentName, CacheEntry>(
				INITIAL_ICON_CACHE_CAPACITY);
		this.mContext = application;

		this.mPackageManager = application.getPackageManager();
		;

		Utilities.BubbleText localBubbleText = new Utilities.BubbleText(
				application);
		this.mBubble = localBubbleText;
		this.mDefaultIcon = makeDefaultIcon();
	}

	public void flush() {
		synchronized (this.mCache) {
			this.mCache.clear();
			return;
		}
	}

	public Bitmap getIcon(final ComponentName paramComponentName,
			final ResolveInfo resolveInfo) {
		return cacheLocked(paramComponentName, resolveInfo).icon;
	}

	public Bitmap getIcon(final Intent intent) {
		synchronized (this.mCache) {
			ResolveInfo localResolveInfo = this.mPackageManager
					.resolveActivity(intent, 0);
			ComponentName localComponentName = intent.getComponent();

			if ((localResolveInfo == null) || (localComponentName == null)) {
				return this.mDefaultIcon;
			}

			return cacheLocked(localComponentName, localResolveInfo).icon;
		}
	}

	public void getTitleAndIcon(final ApplicationInfo appInfo,
			final ResolveInfo info) {
		synchronized (this.mCache) {

			if (appInfo.componentName == null) {
				appInfo.componentName = new ComponentName(
						info.activityInfo.packageName, info.activityInfo.name);
			}

			CacheEntry localCacheEntry = cacheLocked(appInfo.componentName,
					info);

			if (localCacheEntry.titleBitmap == null) {
				localCacheEntry.titleBitmap = this.mBubble
						.createTextBitmap(localCacheEntry.title);
			}

			appInfo.title = localCacheEntry.title;

			appInfo.titleBitmap = localCacheEntry.titleBitmap;
			appInfo.iconBitmap = localCacheEntry.icon;
			appInfo.iconBgBitmap = localCacheEntry.iconBgBitmap;

			int i = info.activityInfo.applicationInfo.flags;

			if (((i & 0x1) != 0) || ((i & 0x80) != 0)) {
				appInfo.systemApp = true;
			} else {
				appInfo.systemApp = false;
			}
		}
	}

	public void remove(final ComponentName paramComponentName) {
		synchronized (this.mCache) {
			this.mCache.remove(paramComponentName);
		}
	}

	private CacheEntry cacheLocked(final ComponentName componentName,
			final ResolveInfo resolveInfo) {

		// Log.e(TAG,"cacheLocked "+componentName.getPackageName());

		CacheEntry localCacheEntry = (CacheEntry) this.mCache
				.get(componentName);

		if (localCacheEntry == null) {
			localCacheEntry = new CacheEntry();
			this.mCache.put(componentName, localCacheEntry);

			localCacheEntry.title = resolveInfo.loadLabel(this.mPackageManager)
					.toString();

			if (localCacheEntry.title == null) {
				localCacheEntry.title = resolveInfo.activityInfo.name;
			}

			if (localCacheEntry.icon == null) {
				Drawable localDrawable = resolveInfo.activityInfo
						.loadIcon(this.mPackageManager);
				localCacheEntry.icon = Utilities.createIconBitmap(
						localDrawable, this.mContext, componentName);
			}
		}

		return localCacheEntry;
	}

	private Bitmap makeDefaultIcon() {
		Drawable localDrawable = this.mPackageManager.getDefaultActivityIcon();
		int i = Math.max(localDrawable.getIntrinsicWidth(), 1);
		int j = Math.max(localDrawable.getIntrinsicHeight(), 1);
		Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;
		Bitmap localBitmap = Bitmap.createBitmap(i, j, localConfig);
		Canvas localCanvas = new Canvas(localBitmap);
		int k = localBitmap.getWidth();
		int m = localBitmap.getHeight();
		localDrawable.setBounds(0, 0, k, m);
		localDrawable.draw(localCanvas);

		return localBitmap;
	}

	class CacheEntry {
		public Bitmap icon;
		public Bitmap iconBgBitmap;
		public Bitmap titleBitmap;
		public String title;
	}
}
